package avicit.bdp.lineage.druid.process.sqlexpr;

import avicit.bdp.lineage.druid.anotation.SQLObjectType;
import avicit.bdp.lineage.druid.process.ProcessorRegister;
import avicit.bdp.lineage.druid.process.SqlExprContent;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * SQLMethodInvokeExpr
 * eg L <p>select substring(a1,a2) as c</p>
 * </p>
 */
@SQLObjectType(clazz = SQLMethodInvokeExpr.class)
public class SQLMethodInvokeExprProcessor implements SQLExprProcessor {

    @Override
    public void process(String dbType, SQLExpr expr, SqlExprContent content) {
        SQLMethodInvokeExpr sqlMethodInvokeExpr = (SQLMethodInvokeExpr) expr;
        this.getAllCaseExprChild(sqlMethodInvokeExpr)
                .forEach(ep -> ProcessorRegister.getSQLExprProcessor(ep.getClass()).process(dbType, ep, content));
    }

    private List<SQLExpr> getAllCaseExprChild(SQLMethodInvokeExpr expr) {
        List<SQLExpr> list = new ArrayList<>();
        Optional.ofNullable(expr.getOwner()).ifPresent(list::add);
        Optional.ofNullable(expr.getFrom()).ifPresent(list::add);
        Optional.ofNullable(expr.getUsing()).ifPresent(list::add);
        Optional.ofNullable(expr.getFor()).ifPresent(list::add);
        if (CollectionUtils.isNotEmpty(expr.getArguments())) {
            handleSpecialMethodArguments(expr, list);
        }
        return list;
    }
    /**
     * 针对不同的函数方法，特殊处理函数参数
     *
     * @param	expr
     * @param	list
     * @return void
     *
     */
    private void handleSpecialMethodArguments(SQLMethodInvokeExpr expr, List<SQLExpr> list) {
        switch (expr.getMethodName()) {
            case "if":
                // 去掉第一个判断字段
                list.add(expr.getArguments().get(1));
                list.add(expr.getArguments().get(2));
                break;
            default:
                list.addAll(expr.getArguments());
        }
    }
}
